package config

import (
	"fmt"
	"os"
	"path/filepath"
	"strconv"

	"github.com/joho/godotenv"
)

const (
	EnvDevelopment = "development"
	EnvTest        = "test"
	EnvProduction  = "production"
)

type MySQLConfig struct {
	Host            string
	Port            int
	Username        string
	Password        string
	Database        string
	MaxIdleConns    int
	MaxOpenConns    int
	ConnMaxLifetime int
}

type RedisConfg struct {
	Host      string
	Port      int
	Password  string
	DefaultDb int
}

type ServerConfig struct {
	Port int
	Mode string
}

type JWtConfig struct {
	SecretKey string
}

type LogConfig struct {
	LogPath string
}

type Config struct {
	Env    string
	MySql  MySQLConfig
	Server ServerConfig
	Redis  RedisConfg
	JWt    JWtConfig
	Log    LogConfig
}

func (c *MySQLConfig) DSN() string {
	return fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local",
		c.Username, c.Password, c.Host, c.Port, c.Database)
}

func Load(env string) *Config {
	envFile := fmt.Sprintf(".env.%s", env)

	wd, _ := os.Getwd()

	fmt.Println(wd)

	path := filepath.Join(wd, fmt.Sprintf("../%s", envFile))

	if err := godotenv.Load(path); err != nil {
		fmt.Printf("找不到%s配置文件, %v\n", path, err)

		if err := godotenv.Load(); err != nil {
			fmt.Printf("找不到.env配置文件, %v\n", err)
		}
	}

	if env == "local.development" {
		env = "development"
	}

	return &Config{
		Env: env,
		MySql: MySQLConfig{
			Host:            getEnv("MYSQL_HOST", "localhost"),
			Port:            getEnv("MYSQL_PORT", 3306),
			Username:        getEnv("MYSQL_USERNAME", "root"),
			Password:        getEnv("MYSQL_PASSWORD", ""),
			Database:        getEnv("MYSQL_DATABASE", "good_house"),
			MaxIdleConns:    getEnv("MYSQL_MAX_IDLE_CONNS", 10),
			MaxOpenConns:    getEnv("MYSQL_MAX_OPEN_CONNS", 100),
			ConnMaxLifetime: getEnv("MYSQL_CONN_MAX_LIFETIME", 3600),
		},
		Server: ServerConfig{
			Port: getEnv("SERVER_PORT", 8080),
			Mode: getEnv("GIN_MODE", "debug"),
		},
		Redis: RedisConfg{
			Host:      getEnv("REDIS_HOST", "localhost"),
			Port:      getEnv("REDIS_PORT", 6379),
			Password:  getEnv("REDIS_PASSWROD", ""),
			DefaultDb: getEnv("REDIS_DEFAULT_DB", 0),
		},
		JWt: JWtConfig{
			SecretKey: getEnv("JWT_SECRET_KEY", "123456"),
		},
		Log: LogConfig{
			LogPath: getEnv("GIN_LOG_PATH", "./"),
		},
	}
}

func getEnv[T any](key string, defaultValue T) T {
	if value, exists := os.LookupEnv(key); exists {
		switch any(defaultValue).(type) {
		case string:
			return any(value).(T)
		case int:
			v, _ := strconv.Atoi(value)
			return any(v).(T)
		default:
			return defaultValue
		}
	}
	return defaultValue
}
